<template>
  <Card dis-hover :bordered="false">
    <Tree :data="data" :render="renderContent"></Tree>
    <Modal
      :mask-closable="false"
      v-model="addModal"
      :title="edit == 'create' ? '新增' : '编辑'"
      :footer-hide="true"
      :draggable="true"
    >
      <Form
        ref="create"
        :model="departmentInfo"
        :rules="rules"
        :label-width="90"
      >
        <FormItem label="部门名称" prop="department_name" required>
          <Input
            v-model="departmentInfo.department_name"
            placeholder="请输入部门名称"
            :maxlength="30"
          />
        </FormItem>
        <FormItem label="数据权限" prop="department_name" required>
          <Select
            placeholder="数据权限"
            v-model="departmentInfo.data_level"
            @on-open-change="showAll"
            :filterable="authorityList.length >= 10"
            clearable
          >
            <Option
              v-for="item in authorityList"
              :value="item.value"
              :key="item.value"
              >{{ item.label }}</Option
            >
          </Select>
        </FormItem>
        <FormItem label="角色" prop="select_role_ids" required>
          <Select
            placeholder="请选择角色"
            v-model="departmentInfo.select_role_ids"
            multiple
            :filterable="roleList.length >= 10"
            @on-change="changeRole"
            clearable
          >
            <Option
              v-for="item in roleList"
              :value="item.value + ''"
              :key="item.value"
              >{{ item.label }}</Option
            >
          </Select>
        </FormItem>
        <FormItem label="默认角色" prop="select_role_ids" required>
          <Select
            placeholder="请选择默认角色"
            v-model="departmentInfo.default_role_id"
            @on-open-change="changeOpen"
            :filterable="defaultRoleList.length >= 10"
            clearable
          >
            <Option
              v-for="item in defaultRoleList"
              :value="+item.value"
              :key="item.value"
              >{{ item.label }}</Option
            >
          </Select>
        </FormItem>
        <FormItem
          label="部门负责人"
          prop="leader_member_ids"
          v-if="leaderList.length > 0 && departmentInfo.data_level == 1"
        >
          <Select
            placeholder="部门负责人"
            v-model="departmentInfo.leader_member_ids"
            multiple
            :filterable="leaderList.length >= 10"
            clearable
          >
            <Option
              v-for="item in leaderList"
              :value="item.value + ''"
              :key="item.value"
              >{{ item.label }}</Option
            >
          </Select>
        </FormItem>
      </Form>
      <div slot="footer" style="text-align: right">
        <Button type="default" @click="addModal = false">取消</Button>
        <Button
          type="primary"
          @click="ok"
          style="margin-left: 10px"
          :loading="btnLoading"
          >确定</Button
        >
      </div>
    </Modal>
  </Card>
</template>
<script>
import { resolveComponent } from "vue";
import {
  departmentList,
  createDepartment,
  deleteDepartment,
  departmentInfo,
  updateDepartment,
  delInfo,
  departmentMove,
} from "@api/department.js";
export default {
  data() {
    return {
      data: [
        {
          children: [],
          department_name: "新媒体系统",
          id: "0",
          level: "0",
        },
      ],
      btnLoading: false,
      loading: false,
      addModal: false,
      edit: "create",
      resData: "",
      currentId: "",
      targetId: "",
      pid: "",
      level: "",
      defaultRoleList: [],
      roleList: [],
      authorityList: [],
      leaderList: [],
      departmentInfo: {
        pid: "",
        department_name: "",
        data_level: "",
        select_role_ids: [],
        default_role_id: "",
        leader_member_ids: [],
      },
      rules: {
        department_name: [{ required: true, message: "请输入部门名称" }],
        data_level: [{ required: true, message: "请选择数据权限" }],
        select_role_ids: [{ required: true, message: "请选择角色" }],
        default_role_id: [{ required: true, message: "请选择默认角色" }],
      },
    };
  },
  mounted() {
    this.getData();
  },
  methods: {
    showAll(e) {
      if (e) {
        let downList = document.querySelectorAll(
          ".ivu-select-dropdown-list .ivu-select-item"
        );
        downList.forEach((item) => {
          item.style.display = "block";
        });
      }
    },
    changeOpen(e) {
      if (e) {
        this.defaultRoleList = [];
        this.departmentInfo.select_role_ids.forEach((item) => {
          this.roleList.forEach((el) => {
            if (item == el.value) {
              this.defaultRoleList.push(el);
            }
          });
        });
        this.showAll(e);
      }
    },
    changeRole(e) {
      if (!e.includes(this.departmentInfo.default_role_id + "")) {
        this.departmentInfo.default_role_id = "";
      }
    },
    getData() {
      departmentList()
        .then((res) => {
          this.data[0].children = res;
          this.data = this.changeData(this.data);
        })
        .finally(() => {});
    },
    append(data, type) {
      if (type == "create" && data.level == 3) {
        this.$Message.error("此部门已是第三级，无法添加子级！");
        return;
      }
      if (type == "edit" && data.id == 0) {
        return;
      }
      this.edit = type;
      this.addModal = true;
      let params = {
        id: data.id,
        scenario: type,
      };
      this.$refs.create.resetFields();
      departmentInfo(params).then((res) => {
        this.authorityList = res.condition.data_level;
        this.roleList = res.condition.role;
        this.defaultRoleList = [];
        this.leaderList = res.condition.leader_member;
        this.departmentInfo = {
          pid: data.id,
          department_name: "",
          data_level: "",
          select_role_ids: [],
          default_role_id: "",
          leader_member_ids: [],
        };

        if (type == "edit") {
          res.select_role_ids.forEach((item) => {
            this.roleList.forEach((el) => {
              if (item == el.value) {
                this.defaultRoleList.push(el);
              }
            });
          });
          this.departmentInfo = {
            pid: res.id,
            department_name: res.department_name,
            data_level: res.data_level,
            select_role_ids: res.select_role_ids,
            default_role_id: res.default_role_id,
            leader_member_ids: res.leader_member_ids,
          };
        }
      });
    },
    editDepartment() {
      this.btnLoading = true;
      if (this.edit == "create") {
        let params = {
          pid: this.departmentInfo.pid,
          department_name: this.departmentInfo.department_name,
          data_level: this.departmentInfo.data_level,
          select_role_ids: this.departmentInfo.select_role_ids,
          default_role_id: this.departmentInfo.default_role_id,
        };
        createDepartment(params)
          .then((res) => {
            this.$Message.success("新增成功");
            this.addModal = false;
            this.btnLoading = false;
            this.getData();
          })
          .catch(() => {
            this.btnLoading = false;
          });
      } else {
        let params =
          this.departmentInfo.data_level == 1
            ? {
                id: this.departmentInfo.pid,
                department_name: this.departmentInfo.department_name,
                data_level: this.departmentInfo.data_level,
                select_role_ids: this.departmentInfo.select_role_ids,
                default_role_id: this.departmentInfo.default_role_id,
                leader_member_ids: this.departmentInfo.leader_member_ids,
              }
            : {
                id: this.departmentInfo.pid,
                department_name: this.departmentInfo.department_name,
                data_level: this.departmentInfo.data_level,
                select_role_ids: this.departmentInfo.select_role_ids,
                default_role_id: this.departmentInfo.default_role_id,
                leader_member_ids: [],
              };
        updateDepartment(params)
          .then((res) => {
            this.$Message.success("编辑成功");
            this.addModal = false;
            this.btnLoading = false;
            this.getData();
          })
          .catch(() => {
            this.btnLoading = false;
          });
      }
    },
    ok() {
      this.$refs.create.validate((valid) => {
        if (valid) {
          this.editDepartment();
        } else {
          this.addModal = true;
          return;
        }
      });
    },
    remove(data) {
      delInfo({ id: data.id }).then((res) => {
        if (res.has_child > 0) {
          this.$Message.error("此部门下含有子部门，不允许删除！");
          return;
        }
        if (res.member_cnt > 0) {
          this.$Modal.confirm({
            title: "删除提示",
            content: "此部门下有【" + res.member_cnt + "】个人员，确定删除？",
            onOk: () => {
              deleteDepartment({ id: data.id }).then(() => {
                this.$Message.success("删除成功");
                this.getData();
              });
            },
          });
        } else {
          this.$Modal.confirm({
            title: "删除提示",
            content: "是否确认删除此部门，删除后不可恢复",
            onOk: () => {
              deleteDepartment({ id: data.id }).then(() => {
                this.$Message.success("删除成功");
                this.getData();
              });
            },
          });
        }
      });
    },
    maxLevel(data, level) {
      if (data.children && data.children.length > 0) {
        level++;
        data.children.forEach((item) => {
          if (item.children && item.children.length > 0) {
            let child_level = this.maxLevel(item, level);
            if (child_level > level) {
              level = child_level;
              return true;
            }
          }
        });
      }
      return level;
    },
    changeData(data) {
      data.forEach((item) => {
        item.expand = true;
        if (item.children && item.children.length > 0) {
          this.changeData(item.children);
        }
      });
      return data;
    },
    findData(id, list) {
      if (list && list.length > 0) {
        list.forEach((item, key) => {
          if (item.id == id) {
            return (this.resData = item);
          } else if (item.children && item.children.length > 0) {
            this.findData(id, item.children);
          }
        });
      }
      return this.resData;
    },
    delItem(id, list) {
      list.forEach((item, index) => {
        if (item.id == id) {
          list.splice(index, 1);
        } else if (item.children && item.children.length > 0) {
          return this.delItem(id, item.children);
        }
      });
    },
    changeLevel(level, list) {
      list.level = level;
      if (list.children && list.children.length > 0) {
        level = level + 1;
        list.children.forEach((item) => {
          this.changeLevel(level, item);
        });
      }

      return list;
    },
    addItem(id, list, data) {
      list.forEach((item, index) => {
        if (item.id == id) {
          item.children = item.children ? item.children : [];
          data = this.changeLevel(parseInt(item.level) + 1, data);
          item.children.push(data);
          return;
        } else if (item.children && item.children.length > 0) {
          return this.addItem(id, item.children, data);
        }
      });
    },
    sortItem(targetId, list, data) {
      list.forEach((item, index) => {
        if (item.id == targetId) {
          data = this.changeLevel(parseInt(item.level), data);
          list.splice(index, 0, data);
          targetId = -1;
          return;
        } else if (item.children && item.children.length > 0) {
          return this.sortItem(targetId, item.children, data);
        }
      });
    },
    findPid(id, list) {
      list.children.forEach((item) => {
        if (item.id == id) {
          return (this.pid = list.id);
        } else if (item.children && item.children.length > 0) {
          this.findPid(id, item);
        }
      });
      return this.pid;
    },
    editTree(currentId, targetId, sortId) {
      this.pid = 0;
      let pid = targetId;
      if (sortId) {
        pid = this.findPid(targetId, this.data[0]);
      }

      departmentMove({
        id: currentId,
        pid: pid,
        after_id: sortId ? sortId : 0,
      })
        .then(() => {
          this.getData();
        })
        .catch((err) => {
          this.getData();
          return false;
        });
    },
    renderContent(h, { root, node, data }) {
      return h(
        "span",
        {
          style: {
            display: "flex",
            width: "100%",
            justifyContent: "space-between",
            alignItems: "center",
            boxSize: "border-box",
          },
          pvalue: data.id,
          class: "dargBefore",
          draggable: true,
          onDragstart: (e) => {
            this.currentId = data.id;
            this.level = data.level;
          },
          onDragover: (e) => {
            e.preventDefault();
          },
          onDragenter: (e) => {
            if (e.target.getAttribute("pvalue") == 0) {
              return;
            }
            e.target.classList.add("active");
          },
          onDragleave: (e) => {
            e.target.classList.remove("active");
          },
          onDrop: (e) => {
            e.preventDefault();

            this.targetId = data.id; //目标id
            let res = this.findData(this.currentId, this.data);
            //判断是否被移动对象是否是目标对象的父级
            if (this.level < data.level) {
              this.resData = "";
              var ischild = this.findData(this.targetId, res.children);
              if (ischild) {
                e.target.classList.remove("active");
                return;
              }
            }
            //判断是否被移动对象和目标对象是否相同
            if (this.currentId == this.targetId) {
              e.target.classList.remove("active");
              return;
            } else if (e.target.getAttribute("pvalue")) {
              //是否是排序
              //判断目标对象是否是顶级部门
              if (this.targetId == 0) {
                return;
              }
              if (this.level < data.level) {
                let itemLevel = this.maxLevel(res, 1);
                if (parseInt(itemLevel) + parseInt(data.level) > 4) {
                  this.$Message.error("最大层级不能超过3！");
                  e.target.classList.remove("active");
                  return;
                }
              }
              if (
                this.findPid(this.targetId, this.data[0]) !=
                this.findPid(this.currentId, this.data[0])
              ) {
                this.$Modal.confirm({
                  title: "温馨提示",
                  content:
                    "改变部门层级会清空该部门下的角色权限，是否继续操作？",
                  onOk: () => {
                    this.delItem(this.currentId, this.data);
                    this.sortItem(
                      e.target.getAttribute("pvalue"),
                      this.data,
                      res
                    );
                    e.target.classList.remove("active");
                    this.editTree(
                      this.currentId,
                      data.id,
                      e.target.getAttribute("pvalue")
                    );
                  },
                  onCancel: () => {
                    e.target.classList.remove("active");
                    return false;
                  },
                });
              } else {
                this.delItem(this.currentId, this.data);
                this.sortItem(e.target.getAttribute("pvalue"), this.data, res);
                e.target.classList.remove("active");
                this.editTree(
                  this.currentId,
                  data.id,
                  e.target.getAttribute("pvalue")
                );
              }
            } else {
              //判断被移动对象是否是目标对象的直接下级
              if (this.level > data.level) {
                this.resData = "";
                let pItem = this.findData(this.targetId, this.data);
                this.resData = "";
                var isprarent = pItem.children
                  ? pItem.children.find((item) => {
                      return item.id == this.currentId;
                    })
                  : "";
                if (isprarent) {
                  e.target.classList.remove("active");
                  return;
                }
              }

              let itemLevel = this.maxLevel(res, 1);
              if (parseInt(itemLevel) + parseInt(data.level) > 3) {
                this.$Message.error("最大层级不能超过3！");
                return;
              }
              this.$Modal.confirm({
                title: "温馨提示",
                content: "改变部门层级会清空该部门下的角色权限，是否继续操作？",
                onOk: () => {
                  this.delItem(this.currentId, this.data);
                  this.addItem(this.targetId, this.data, res);
                  e.target.classList.remove("active");
                  this.editTree(
                    this.currentId,
                    data.id,
                    e.target.getAttribute("pvalue")
                  );
                },
                onCancel: () => {
                  e.target.classList.remove("active");
                  return false;
                },
              });
            }
          },
        },
        {
          default: () => [
            h(
              "span",
              {
                value: data.id,
                class: "departmentTitle",
                onClick: (e) => {
                  this.append(data, "edit");
                },
              },
              { default: () => data.department_name }
            ),
            h(
              resolveComponent("ButtonGroup"),
              { class: "actions" },
              {
                default: () =>
                  data.level != 0
                    ? [
                        h(resolveComponent("Button"), {
                          icon: "md-add",
                          onClick: (e) => {
                            e.stopPropagation();
                            this.append(data, "create");
                          },
                        }),
                        h(resolveComponent("Button"), {
                          icon: "ios-trash",
                          onClick: (e) => {
                            e.stopPropagation();
                            this.remove(data);
                          },
                        }),
                      ]
                    : [
                        h(resolveComponent("Button"), {
                          icon: "md-add",
                          onClick: (e) => {
                            e.stopPropagation();
                            this.append(data, "create");
                          },
                        }),
                      ],
              }
            ),
          ],
        }
      );
    },
  },
};
</script>
<style lang="less" scoped>
// :deep(.ivu-icon-ios-arrow-forward:before) {
//   content: "\f100";
// }
:deep(.ivu-tree-arrow) {
  width: 20px;
  height: 32px;
}
:deep(.ivu-tree-arrow i) {
  font-size: 20px;
}
// :deep(.ivu-tree-arrow-open i) {
//   transform: rotate(0deg);
// }
// :deep(.ivu-tree-arrow-open .ivu-icon-ios-arrow-forward:before) {
//   content: "\f290";
// }
:deep(.dargBefore) {
  position: relative;
  line-height: 32px;
}
:deep(.ivu-btn:hover) {
  border-color: #333;
}
:deep(.ivu-btn-icon-only) {
  border-radius: 0;
  border-color: #333;
}
:deep(.dargBefore:before) {
  position: absolute;
  top: -16px;
  right: 0;
  left: 0;
  display: block;
  height: 20px;
  border-radius: 1px;
  content: "";
}
:deep(.dargBefore.active:before) {
  border-bottom: 2px solid #333;
}
:deep(.ivu-tree ul) {
  font-size: 20px;
}
:deep(.ivu-tree-title) {
  padding: 0;
}
:deep(.ivu-tree-title-selected) {
  background-color: #333;
  .departmentTitle {
    color: #fff;
  }
}
:deep(.ivu-tree-title:hover) {
  background-color: #333;
  .departmentTitle {
    color: #fff;
  }
}
:deep(.actions) {
  display: none;
}
:deep(.departmentTitle) {
  // border: 1px solid #333;
  color: #333;
  padding: 0 10px;
  height: 32px;
  box-sizing: border-box;
}
:deep(.dargBefore:hover) {
  .actions {
    display: block;
  }
}
// :deep(.) {
//   position: relative;
// }
// :deep(.ivu-tree-arrow::before) {
//   content: "";
//   position: absolute;
//   top: 25px;
//   left: 19px;
//   bottom: -25px;
//   width: 1px;
//   border: 1px solid #333;
// }
</style>
